import {
  animate,
  AnimationMetadata,
  AnimationTriggerMetadata,
  group,
  state,
  style,
  transition,
  trigger,
} from '@angular/animations';

const MOTION_DURATION_SCALE = 1;

export const MotionDurationTime = {
  XL: 350,
  LG: 300,
  MD: 250,
  SM: 200,
  XS: 150,
  XSS: 100,
};

export const MotionDuration = {
  /** 350ms */
  XL: `${MotionDurationTime.XL * MOTION_DURATION_SCALE}ms`,
  /** 300ms */
  LG: `${MotionDurationTime.LG * MOTION_DURATION_SCALE}ms`,
  /** 250ms */
  MD: `${MotionDurationTime.MD * MOTION_DURATION_SCALE}ms`,
  /** 200ms */
  SM: `${MotionDurationTime.SM * MOTION_DURATION_SCALE}ms`,
  /** 150ms */
  XS: `${MotionDurationTime.XS * MOTION_DURATION_SCALE}ms`,
  /** 100ms */
  XSS: `${MotionDurationTime.XSS * MOTION_DURATION_SCALE}ms`,
};

/**
 * 动效的曲线
 */
export const MotionFunc = {
  /** 标准曲线 */
  EASE: 'cubic-bezier(0.4, 0, 0.2, 1)',
  /** 加速曲线 */
  EASE_IN: 'cubic-bezier(0.4, 0, 1, 1)',
  /** 减速曲线 */
  EASE_OUT: 'cubic-bezier(0, 0, 0.2, 1)',
  /** 锐利曲线 */
  EASE_IN_OUT: 'cubic-bezier(0.33, 0, 0.67, 1)',
};

/**
 * 取消元素到void状态的动画
 * 使用场景：ngif容器中嵌套使用query和(:enter :leave)类型的动画的组件
 */
export const noAnimationToVoid: AnimationMetadata = transition('* => void', []);

export const DropDownLong: AnimationTriggerMetadata = trigger('DropDownLong', [
  state(
    'visible',
    style({
      opacity: 1,
      transform: 'scaleY(1)',
      transformOrigin: '0% 0%',
    }),
  ),
  state(
    'hidden',
    style({
      opacity: 0,
      transform: 'scaleY(0.4)',
      transformOrigin: '0% 0%',
    }),
  ),
  transition('void => *', [
    style({
      opacity: 0,
      transform: 'scaleY(0.4)',
      transformOrigin: '0% 0%',
    }),
    animate(
      '180ms cubic-bezier(0.25, 0.8, 0.25, 1)',
      style({
        opacity: 1,
        transform: 'scaleY(1)',
        transformOrigin: '0% 0%',
      }),
    ),
  ]),
  transition('* => void', [
    style({
      opacity: 1,
      transform: 'scaleY(1)',
      transformOrigin: '0% 0%',
    }),
    animate(
      '180ms cubic-bezier(0.25, 0.8, 0.25, 1)',
      style({
        opacity: 0,
        transform: 'scaleY(0.4)',
        transformOrigin: '0% 0%',
      }),
    ),
  ]),
  transition('visible => hidden', animate('120ms cubic-bezier(0.25, 0.8, 0.25, 1)')),
  transition('hidden => visible', animate('120ms cubic-bezier(0.25, 0.8, 0.25, 1)')),
]);
export const DropDown: AnimationTriggerMetadata = trigger('DropDown', [
  state(
    'visible',
    style({
      opacity: 1,
      transform: 'scaleY(1)',
      transformOrigin: '0% 0%',
    }),
  ),
  state(
    'hidden',
    style({
      opacity: 0,
      transform: 'scaleY(0)',
      transformOrigin: '0% 0%',
    }),
  ),
  transition('void => visible', [
    style({
      opacity: 0,
      transform: 'scaleY(0)',
      transformOrigin: '0% 0%',
    }),
    animate(
      '180ms cubic-bezier(0.25, 0.8, 0.25, 1)',
      style({
        opacity: 1,
        transform: 'scaleY(1)',
        transformOrigin: '0% 0%',
      }),
    ),
  ]),
  transition('* => void', [
    style({
      opacity: 1,
      transform: 'scaleY(1)',
      transformOrigin: '0% 0%',
    }),
    animate(
      '180ms cubic-bezier(0.25, 0.8, 0.25, 1)',
      style({
        opacity: 0,
        transform: 'scaleY(0)',
        transformOrigin: '0% 0%',
      }),
    ),
  ]),
  transition('visible => hidden', animate('120ms cubic-bezier(0.25, 0.8, 0.25, 1)')),
  transition('hidden => visible', animate('120ms cubic-bezier(0.25, 0.8, 0.25, 1)')),
]);
export const FadeIn: AnimationTriggerMetadata = trigger('FadeIn', [
  state(
    'hidden',
    style({
      opacity: 0,
    }),
  ),
  state(
    'visible',
    style({
      opacity: 1,
    }),
  ),
  transition('visible => hidden', animate('0ms ease-in')),
  transition('hidden => visible', animate('0ms ease-out')),
]);

/**
 * 下拉菜单动画
 */
export const showItem: AnimationTriggerMetadata = trigger('showItem', [
  state('showDown', style({ transform: 'translateY(0)', opacity: 1 })),
  state('hideDown', style({ transform: 'translateY(-0.1rem)', opacity: 0 })),
  state('showUp', style({ transform: 'translateY(0)', opacity: 1 })),
  state('hideUp', style({ transform: 'translateY(0.1rem)', opacity: 0 })),
  transition('* => showDown', [
    group([
      style({ transform: 'translateY(-0.1rem)', opacity: 0 }),
      animate(
        `${MotionDuration.SM} ${MotionFunc.EASE_OUT}`,
        style({
          transform: 'translateY(0)',
        }),
      ),
      animate(
        `${MotionDuration.SM} ${MotionFunc.EASE_IN_OUT}`,
        style({
          opacity: 1,
        }),
      ),
    ]),
  ]),
  transition('showDown => hideDown', [
    group([
      animate(
        `${MotionDuration.XS} ${MotionFunc.EASE_IN}`,
        style({
          transform: 'translateY(-0.1rem)',
        }),
      ),
      animate(
        `${MotionDuration.XS} ${MotionFunc.EASE_IN_OUT}`,
        style({
          opacity: 0,
        }),
      ),
    ]),
  ]),
  transition('* => showUp', [
    style({ transform: 'translateY(0.1rem)', opacity: 0 }),
    group([
      animate(
        `${MotionDuration.SM} ${MotionFunc.EASE_OUT}`,
        style({
          transform: 'translateY(0)',
        }),
      ),
      animate(
        `${MotionDuration.SM} ${MotionFunc.EASE_IN_OUT}`,
        style({
          opacity: 1,
        }),
      ),
    ]),
  ]),
  transition('showUp => hideUp', [
    group([
      animate(
        `${MotionDuration.XS} ${MotionFunc.EASE_IN}`,
        style({
          transform: 'translateY(0.1rem)',
        }),
      ),
      animate(
        `${MotionDuration.XS} ${MotionFunc.EASE_IN_OUT}`,
        style({
          opacity: 0,
        }),
      ),
    ]),
  ]),
]);

/**
 * 下拉菜单子菜单动画
 */
export const showSubItem: AnimationTriggerMetadata = trigger('showSubItem', [
  state(
    'hide',
    style({
      transform: 'translateX(-0.02rem)',
      opacity: 0,
    }),
  ),
  state(
    'show',
    style({
      transform: 'translateX(0.08rem)',
      opacity: 1,
    }),
  ),
  transition(
    '* => show',
    group([
      style({ transform: 'translateX(-0.02rem)', opacity: 0 }),
      animate(`${MotionDuration.SM} ${MotionFunc.EASE}`, style({ transform: 'translateX(0.08rem)' })),
      animate(`${MotionDuration.SM} ${MotionFunc.EASE_IN_OUT}`, style({ opacity: 1 })),
    ]),
  ),
  transition(
    'show => hide',
    group([
      animate(`${MotionDuration.XS} ${MotionFunc.EASE}`, style({ transform: 'translateX(-0.02rem)' })),
      animate(`${MotionDuration.XS} ${MotionFunc.EASE_IN_OUT}`, style({ opacity: 0 })),
    ]),
  ),
]);
